package com.hmy.contract.service.authorizermodify.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.hmy.ccp.datapermission.aop.DataPermission;
import com.hmy.ccp.error.exception.HMYRuntimeException;
import com.hmy.ccp.starter.web.utils.UserContextUtil;
import com.hmy.contract.bo.request.authorizermodify.*;
import com.hmy.contract.bo.request.contract.AuthorizerModifyRequest;
import com.hmy.contract.bo.request.contract.ContractInfoRequest;
import com.hmy.contract.bo.request.contract.OrderAuthorizerRequest;
import com.hmy.contract.bo.response.authorizermodify.AuthorizerModifyResponse;
import com.hmy.contract.bo.response.authorizermodify.AuthorizersModifyRecord;
import com.hmy.contract.bo.response.authorizermodify.QueryModifyHistoryResponse;
import com.hmy.contract.bo.response.contract.ContractInfoResponse;
import com.hmy.contract.common.constant.ContractConstants;
import com.hmy.contract.common.constant.RedisKeyConstants;
import com.hmy.contract.common.utils.CommonCodeGenerator;
import com.hmy.contract.commons.enums.AuthorizerEnum;
import com.hmy.contract.commons.enums.ContractStatusEnum;
import com.hmy.contract.commons.enums.ContractTypeEnum;
import com.hmy.contract.dal.mapper.AuthorizerModifyMapper;
import com.hmy.contract.dal.mapper.ContractMapper;
import com.hmy.contract.dal.po.AuthorizerModifyPo;
import com.hmy.contract.dal.po.ContractPo;
import com.hmy.contract.manager.order.OrderFeignClientManager;
import com.hmy.contract.manager.worklfow.FlowProcessClientManager;
import com.hmy.contract.manager.worklfow.FlowTaskClientManager;
import com.hmy.contract.service.authorizermodify.IAuthorizerModifyService;
import com.hmy.contract.service.contract.IContractService;
import com.hmy.order.api.bo.request.UpdateAuthorizerRequest;
import com.hmy.workflow.api.bo.request.process.RevokeProcessRequest;
import com.hmy.workflow.api.bo.request.process.StartProcessInstanceRequest;
import com.hmy.workflow.api.bo.request.task.ApprovalTaskRequest;
import com.hmy.workflow.api.bo.request.task.QueryNextActiveTaskRequest;
import com.hmy.workflow.api.bo.response.process.StartProcessInstanceResponse;
import com.hmy.workflow.api.bo.response.task.ApprovalTaskResponse;
import com.hmy.workflow.api.enums.ApprovalStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AuthorizerModifyServiceImpl extends ServiceImpl<AuthorizerModifyMapper, AuthorizerModifyPo> implements IAuthorizerModifyService {

    @Resource
    private FlowProcessClientManager flowProcessClient;

    @Resource
    private OrderFeignClientManager orderFeignClient;

    @Resource
    private FlowTaskClientManager flowTaskClient;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private IContractService contractService;

    @Resource
    private ContractMapper contractMapper;

    @Value("${process.definition.authorizer.modify.id}")
    private String processDefinitionId;

    @Autowired
    private DefaultIdentifierGenerator identifierGenerator;

    @Override
    @Transactional
    public Long saveAuthorizerModify(SaveAuthorizerModifyRequest request) {
        log.info("saveAuthorizerModify parameter {}", request);
        ContractPo contract = queryContract(request.getContractId());
        checkSaveParameter(contract, request);
        AuthorizerModifyPo authorizerModify = buildAuthorizerModifyPo(contract, request);
        if (!AuthorizerEnum.Status.REJECT.getStatus().equals(authorizerModify.getStatus())) {
            authorizerModify.setStatus(AuthorizerEnum.Status.DRAFT.getStatus());
        }
        saveOrUpdate(authorizerModify);
        return authorizerModify.getModifyId();
    }

    @Override
    @Transactional
    public Long submitAuthorizerModify(SaveAuthorizerModifyRequest request) {
        log.info("submitAuthorizerModify parameter {}", request);
        ContractPo contract = queryContract(request.getContractId());
        checkSaveParameter(contract, request);
        AuthorizerModifyPo authorizerModify = buildAuthorizerModifyPo(contract, request);
        // 驳回、撤销之后重新提交
        if (request.getModifyId() != null && (AuthorizerEnum.Status.REVOKE.getStatus().equals(authorizerModify.getStatus())
                || AuthorizerEnum.Status.REJECT.getStatus().equals(authorizerModify.getStatus()))) {
            log.info("submitAuthorizerModify retryApprove {}", authorizerModify.getStatus());
            reApprove(authorizerModify, request);
        } else {
            // 首次提交或者编辑之后提交
            authorizerModify.setStatus(AuthorizerEnum.Status.TO_APPROVE.getStatus());
            authorizerModify.setSubStatus(AuthorizerEnum.SubStatus.TO_AREA_MANAGER_APPROVE.getSubStatus());
            // 给区域经理发起审批
            StartProcessInstanceResponse result = sendAreaManagerApprove(authorizerModify);
            if (result.getProcessInstanceId() == null || result.getTaskId() == null) {
                throw new HMYRuntimeException(502000005);
            }
            authorizerModify.setWorkflowId(result.getProcessInstanceId());
            authorizerModify.setTaskId(result.getTaskId());

            saveOrUpdate(authorizerModify);
        }
        return authorizerModify.getModifyId();
    }

    @Override
    @Transactional
    public Boolean deleteAuthorizerModify(Long modifyId) {
        log.info("deleteAuthorizerModify parameter {}", modifyId);
        AuthorizerModifyPo authorizerModify = queryAuthorizerModifyWithException(modifyId);
        if (authorizerModify.getStatus() > AuthorizerEnum.Status.TO_APPROVE.getStatus()) {
            throw new HMYRuntimeException(502100002);
        }
        updateAuthorizerModify(modifyId);
        // 删除工作流
        flowProcessClient.remove(authorizerModify.getWorkflowId());
        return true;
    }

    @Override
    @Transactional
    public Boolean revokeAuthorizerModify(RevokeAuthorizerModifyRequest request) {
        log.info("revokeAuthorizerModify parameter {}", request);
        AuthorizerModifyPo authorizerModify = queryAuthorizerModifyWithException(request.getModifyId());
        if (!AuthorizerEnum.SubStatus.TO_AREA_MANAGER_APPROVE.getSubStatus().equals(authorizerModify.getSubStatus())) {
            throw new HMYRuntimeException(502100005);
        }

        // 发起撤销
        RevokeProcessRequest revokeRequest = new RevokeProcessRequest();
        revokeRequest.setProcessInstanceId(authorizerModify.getWorkflowId());
        revokeRequest.setComment(request.getRemark());
        Map<String, Object> variables = new HashMap<>();
        variables.put("rejectCount", "1");
        revokeRequest.setVariables(variables);
        if (flowProcessClient.revoke(revokeRequest)) {
            AuthorizerModifyPo update = new AuthorizerModifyPo();
            UserContextUtil.initUpdaterInfo(update);
            update.setUpdateTime(LocalDateTime.now());
            update.setStatus(AuthorizerEnum.Status.REVOKE.getStatus());
            update(update, Wrappers.lambdaUpdate(AuthorizerModifyPo.class).eq(AuthorizerModifyPo::getModifyId,
                    request.getModifyId()));
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean approveAuthorizerModify(ApproveAuthorizerModifyRequest approve) {
        log.info("approveAuthorizerModify parameter {}", approve);
        AuthorizerModifyPo authorizerModify = queryAuthorizerModify(approve.getModifyId());
        AuthorizerModifyPo update = new AuthorizerModifyPo();
        UserContextUtil.initUpdaterInfo(update);
        update.setUpdateTime(LocalDateTime.now());
        update.setApproveRemark(approve.getApproveRemark());

        ApprovalTaskRequest approveRequest = new ApprovalTaskRequest();
        approveRequest.setProcessInstanceId(authorizerModify.getWorkflowId());
        approveRequest.setTaskId(approve.getTaskId());
        approveRequest.setComment(approve.getApproveRemark());
        Map<String, Object> variables = new HashMap<>();
        if (AuthorizerEnum.SubStatus.TO_AREA_MANAGER_APPROVE.getSubStatus().equals(authorizerModify.getSubStatus())) {
            // 区域经理审批通过
            if (approve.getApproveResult().getResult().equals(AuthorizerEnum.ApproveResult.PASS.getResult())) {
                update.setSubStatus(AuthorizerEnum.SubStatus.TO_RISK_MANAGER_APPROVE.getSubStatus());

                variables.put("areaManagerApproveResult", AuthorizerEnum.ApproveResult.PASS.getCode());
                approveRequest.setApprovalStatus(ApprovalStatusEnum.PASS.getCode());
                approveRequest.setVariables(variables);
            } else {
                update.setStatus(AuthorizerEnum.Status.REJECT.getStatus());
                update.setSubStatus(AuthorizerEnum.SubStatus.AREA_MANAGER_REJECT.getSubStatus());

                variables.put("businessStatus", AuthorizerEnum.Status.REJECT.getStatus());
                variables.put("businessStatusDesc",
                        AuthorizerEnum.Status.getDesc(AuthorizerEnum.Status.REJECT.getStatus()));
                variables.put("areaManagerApproveResult", AuthorizerEnum.ApproveResult.REJECT.getCode());
                variables.put("rejectCount", "1");
                approveRequest.setVariables(variables);
                approveRequest.setApprovalStatus(ApprovalStatusEnum.REJECT.getCode());
            }
        } else {
            // 风控部长审批通过
            if (approve.getApproveResult().getResult().equals(AuthorizerEnum.ApproveResult.PASS.getResult())) {
                variables.put("riskManagerApproveResult", AuthorizerEnum.ApproveResult.PASS.getCode());
                variables.put("businessStatus", AuthorizerEnum.Status.FINISH.getStatus());
                variables.put("businessStatusDesc",
                        AuthorizerEnum.Status.getDesc(AuthorizerEnum.Status.FINISH.getStatus()));
                approveRequest.setVariables(variables);
                approveRequest.setApprovalStatus(ApprovalStatusEnum.PASS.getCode());

                update.setStatus(AuthorizerEnum.Status.FINISH.getStatus());

                // 更新合同授权人
                updateContractAuthorizer(authorizerModify);

                // 更新订单授权人
                updateOrderAuthorizer(authorizerModify);
            } else {
                variables.put("riskManagerApproveResult", AuthorizerEnum.ApproveResult.REJECT.getCode());
                variables.put("rejectCount", "1");
                variables.put("businessStatus", AuthorizerEnum.Status.REJECT.getStatus());
                variables.put("businessStatusDesc",
                        AuthorizerEnum.Status.getDesc(AuthorizerEnum.Status.REJECT.getStatus()));
                approveRequest.setVariables(variables);
                approveRequest.setApprovalStatus(ApprovalStatusEnum.REJECT.getCode());

                update.setStatus(AuthorizerEnum.Status.REJECT.getStatus());
                update.setSubStatus(AuthorizerEnum.SubStatus.TO_RISK_MANAGER_REJECT.getSubStatus());
            }
        }
        ApprovalTaskResponse response = flowTaskClient.complete(approveRequest);
        if (!response.getSuccess()) {
            throw new HMYRuntimeException(502000006);
        }
        update(update, Wrappers.lambdaUpdate(AuthorizerModifyPo.class).eq(AuthorizerModifyPo::getModifyId,
                approve.getModifyId()));
        return true;
    }

    @Override
    public AuthorizerModifyResponse queryAuthorizerModifyDetail(QueryAuthorizerModifyRequest queryRequest) {
        log.info("queryAuthorizerModify parameter {}", queryRequest);
        AuthorizerModifyPo authorizerModify = queryAuthorizerModify(queryRequest.getModifyId());
        if (authorizerModify == null) {
            return new AuthorizerModifyResponse();
        }
        ContractInfoResponse contractInfo = queryContractResponse(authorizerModify.getContractId());
        AuthorizerModifyResponse res = BeanUtil.copyProperties(contractInfo, AuthorizerModifyResponse.class);
        res.setCustomerName(authorizerModify.getCustomerName());
        res.setModifyReason(authorizerModify.getModifyReason());
        res.setFileUrl(authorizerModify.getFileUrl());
        res.setCurrAuthorizerInfo(authorizerModify.getCurrAuthorizerInfo());
        res.setModifyId(authorizerModify.getModifyId());
        res.setModifyNo(authorizerModify.getModifyNo());
        res.setModifyStatus(authorizerModify.getStatus());
        res.setModifySubStatus(authorizerModify.getSubStatus());
        res.setModifyStatusDesc(AuthorizerEnum.Status.getDesc(authorizerModify.getStatus()));
        res.setContractTypeDesc(ContractTypeEnum.getDescByType(authorizerModify.getContractType()));
        res.setWorkflowId(authorizerModify.getWorkflowId());
        res.setApproveRemark(authorizerModify.getApproveRemark());
        return res;
    }

    @Override
    @DataPermission(sql = "com.hmy.contract.dal.mapper.AuthorizerModifyMapper.selectPage", userField =
            "sale_manager_id", deptField = "dept_id")
    public Page<AuthorizerModifyResponse> queryAuthorizerModifyPage(QueryAuthorizerModifyRequest request) {
        log.info("queryAuthorizerModifyPage parameter {}", request);
        Page<AuthorizerModifyPo> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<AuthorizerModifyPo> pageSource = this.page(page, setQueryCondition(request));
        List<AuthorizerModifyResponse> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(pageSource.getRecords())) {
            pageSource.getRecords().forEach(authorizerModify -> {
                AuthorizerModifyResponse res = new AuthorizerModifyResponse();
                BeanUtil.copyProperties(authorizerModify, res);
                res.setModifyStatus(authorizerModify.getStatus());
                res.setModifySubStatus(authorizerModify.getSubStatus());
                res.setModifyStatusDesc(AuthorizerEnum.Status.getDesc(authorizerModify.getStatus()));
                res.setContractTypeDesc(ContractTypeEnum.getDescByType(authorizerModify.getContractType()));
                list.add(res);
            });
        }
        Page<AuthorizerModifyResponse> pageTarget = new Page<>();
        pageTarget.setRecords(list);
        pageTarget.setTotal(pageSource.getTotal());
        pageTarget.setCurrent(pageSource.getCurrent());
        pageTarget.setPages(pageSource.getPages());
        pageTarget.setSize(pageSource.getSize());
        return pageTarget;
    }

    @Override
    public QueryModifyHistoryResponse queryAuthorizerModifyHistory(QueryAuthorizerModifyHistoryRequest request) {
        LambdaQueryWrapper<AuthorizerModifyPo> query = Wrappers.lambdaQuery(AuthorizerModifyPo.class);
        query.eq(AuthorizerModifyPo::getIsDeleted, false);
        query.eq(StringUtils.isNotBlank(request.getContractNo()), AuthorizerModifyPo::getContractNo,
                request.getContractNo());
        query.eq(request.getOrderId() != null, AuthorizerModifyPo::getOrderId, request.getOrderId());
        query.orderByAsc(AuthorizerModifyPo::getCreateTime);
        List<AuthorizerModifyPo> list = this.list(query);
        QueryModifyHistoryResponse response = new QueryModifyHistoryResponse();
        if (CollectionUtil.isEmpty(list)) {
            return response;
        }
        // 初始授权人信息
        // 过滤掉空
        //([{"authorizerName": "李逵", "authorizerPhone": "111111", "authorizerIdCardNumber": "410527199312044614"}, {}])
        List<AuthorizerModifyRequest> initialAuthorizers = new ArrayList<>();
        JSONArray.parseArray(list.get(0).getPreAuthorizerInfo(), AuthorizerModifyRequest.class).forEach(initialAuthorizer -> {
                    if (initialAuthorizer.getAuthorizerIdCardNumber() != null) {
                        initialAuthorizer.setTypeDesc("初始创建授权人");
                        initialAuthorizers.add(initialAuthorizer);
                    }
                }
        );
        response.setInitialAuthorizers(initialAuthorizers);

        // 变更记录
        List<AuthorizersModifyRecord> modifyAuthorizers = new ArrayList<>();
        list.forEach(Authorizer -> {
            AuthorizersModifyRecord modifyRecord = new AuthorizersModifyRecord();
            List<AuthorizerModifyRequest> modifyAuthorizer = JSONArray.parseArray(Authorizer.getDiffAuthorizerInfo(),
                    AuthorizerModifyRequest.class);
            modifyRecord.setModifyNo(Authorizer.getModifyNo());
            modifyRecord.setModifyId(Authorizer.getModifyId());
            modifyRecord.setModifyReason(Authorizer.getModifyReason());
            modifyRecord.setModifyEndTime(Authorizer.getUpdateTime());
            modifyRecord.setModifyAuthorizerRecord(modifyAuthorizer);
            modifyAuthorizers.add(modifyRecord);
        });
        response.setModifyAuthorizers(modifyAuthorizers);
        return response;
    }

    /**
     * 查询授权变更信息
     *
     * @param id 主键
     * @return 授权变更信息
     */
    private AuthorizerModifyPo queryAuthorizerModify(Long id) {
        return getOne(Wrappers.lambdaQuery(AuthorizerModifyPo.class).eq(AuthorizerModifyPo::getIsDeleted, false)
                .eq(AuthorizerModifyPo::getModifyId, id));
    }

    /**
     * 查询授权变更信息
     *
     * @param id 主键
     * @return 授权变更信息
     */
    private AuthorizerModifyPo queryAuthorizerModifyWithException(Long id) {
        AuthorizerModifyPo authorizerModify =
                getOne(Wrappers.lambdaQuery(AuthorizerModifyPo.class).eq(AuthorizerModifyPo::getIsDeleted, false)
                        .eq(AuthorizerModifyPo::getModifyId, id));
        if (authorizerModify == null) {
            throw new HMYRuntimeException(502100001);
        }
        return authorizerModify;
    }

    /**
     * 查询合同
     *
     * @param contractId 合同id
     */
    private ContractInfoResponse queryContractResponse(Long contractId) {
        ContractInfoRequest request = new ContractInfoRequest();
        request.setContractId(contractId);
        return contractService.contractInfo(request);
    }

    /**
     * 查询合同
     *
     * @param contractId 合同id
     */
    private ContractPo queryContract(Long contractId) {
        LambdaQueryWrapper<ContractPo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractPo::getContractId, contractId);
        ContractPo contractPo = contractMapper.selectOne(wrapper);
        if (contractPo == null || contractPo.getIsDeleted()) {
            throw new HMYRuntimeException(502000002);
        }
        return contractPo;
    }

    /**
     * 参数校验
     *
     * @param contract 合同对象
     * @param request  请求对象
     */
    private void checkSaveParameter(ContractPo contract, SaveAuthorizerModifyRequest request) {
        if (ContractTypeEnum.ELECTRONIC_CONTRACT.getType().equals(contract.getContractType())) {
            if (!ContractStatusEnum.SIGNED.getStatus().equals(contract.getStatus())) {
                throw new HMYRuntimeException(502100003);
            }
        }
        if (ContractTypeEnum.PAPER_CONTRACT.getType().equals(contract.getContractType())) {
            if (!ContractStatusEnum.APPROVED.getStatus().equals(contract.getStatus())) {
                throw new HMYRuntimeException(502100003);
            }
        }
        Gson gson = new Gson();
        OrderAuthorizerRequest[] authorizers = gson.fromJson(contract.getAuthorizerInfo(),
                OrderAuthorizerRequest[].class);
        List<OrderAuthorizerRequest> list = request.getCurrAuthorizerInfo();
        for (OrderAuthorizerRequest oldAuthorizer : authorizers) {
            for (OrderAuthorizerRequest newAuthorizer : list) {
                if (oldAuthorizer.getAuthorizerIdCardNumber() == null) {
                    continue;
                }
                if (!oldAuthorizer.getAuthorizerIdCardNumber().equals(newAuthorizer.getAuthorizerIdCardNumber())) {
                    if (oldAuthorizer.getAuthorizerPhone().equals(newAuthorizer.getAuthorizerPhone())) {
                        throw new HMYRuntimeException(502100004);
                    }
                }
            }
        }
        AuthorizerModifyPo authorizerModify = getOne(Wrappers.lambdaQuery(AuthorizerModifyPo.class)
                .ne(AuthorizerModifyPo::getStatus, AuthorizerEnum.Status.FINISH.getStatus())
                .ne(AuthorizerModifyPo::getStatus, AuthorizerEnum.Status.CANCEL.getStatus())
                .eq(AuthorizerModifyPo::getContractId, contract.getContractId())
                .ne(request.getModifyId() != null, AuthorizerModifyPo::getModifyId, request.getModifyId())
                .eq(AuthorizerModifyPo::getIsDeleted, false));
        if (authorizerModify != null) {
            throw new HMYRuntimeException(502100007);
        }
    }


    /**
     * 设置查询条件
     *
     * @param request 请求对象
     * @return 查询条件
     */
    private LambdaQueryWrapper<AuthorizerModifyPo> setQueryCondition(QueryAuthorizerModifyRequest request) {
        LambdaQueryWrapper<AuthorizerModifyPo> query = Wrappers.lambdaQuery();
        query.eq(AuthorizerModifyPo::getIsDeleted, false);
        query.eq(request.getStatus() != null, AuthorizerModifyPo::getStatus, request.getStatus());
        if (StringUtils.isNotBlank(request.getQueryKey())) {
            query.and(wra -> wra.like(AuthorizerModifyPo::getContractNo, request.getQueryKey())
                    .or().like(AuthorizerModifyPo::getModifyNo, request.getQueryKey())
                    .or().like(AuthorizerModifyPo::getCustomerName, request.getQueryKey())
            );
        }
        query.orderByDesc(AuthorizerModifyPo::getCreateTime);
        return query;
    }

    /**
     * 构建AuthorizerModifyPo对象
     *
     * @param contract 合同
     * @return AuthorizerModifyPo对象
     */
    private AuthorizerModifyPo buildAuthorizerModifyPo(ContractPo contract, SaveAuthorizerModifyRequest request) {
        AuthorizerModifyPo authorizerModifyPo;
        if (request.getModifyId() != null) {
            authorizerModifyPo = queryAuthorizerModifyWithException(request.getModifyId());
            UserContextUtil.initUpdaterInfo(authorizerModifyPo);
            authorizerModifyPo.setUpdateTime(LocalDateTime.now());
            authorizerModifyPo.setModifyId(request.getModifyId());
        } else {
            authorizerModifyPo = new AuthorizerModifyPo();
            authorizerModifyPo.setModifyId(identifierGenerator.nextId(authorizerModifyPo));
            UserContextUtil.initCreatorInfo(authorizerModifyPo);
            UserContextUtil.initUpdaterInfo(authorizerModifyPo);
            authorizerModifyPo.setCreateTime(LocalDateTime.now());
            authorizerModifyPo.setUpdateTime(LocalDateTime.now());
            authorizerModifyPo.setModifyNo(CommonCodeGenerator.getNextCode(redisTemplate,
                    ContractConstants.AUTHORIZER_MODIFY_CODE_PREFIX, RedisKeyConstants.AUTHORIZER_MODIFY_CODE));
            // 冗余合同常用字段
            authorizerModifyPo.setContractId(contract.getContractId());
            authorizerModifyPo.setContractNo(contract.getContractNo());
            authorizerModifyPo.setContractType(contract.getContractType());
            authorizerModifyPo.setProjectName(contract.getProjectName());
            authorizerModifyPo.setOrderId(contract.getOrderId());
            authorizerModifyPo.setOrderNo(contract.getOrderNo());
            authorizerModifyPo.setCustomerId(contract.getCustomerId());
            authorizerModifyPo.setCustomerName(contract.getCustomerName());
            authorizerModifyPo.setContractStatus(contract.getStatus());
            authorizerModifyPo.setSaleManagerId(contract.getSaleManagerId());
            authorizerModifyPo.setSaleManagerName(contract.getSaleManagerName());
            authorizerModifyPo.setDeptId(contract.getDeptId());
        }
        Gson gson = new Gson();
        OrderAuthorizerRequest[] pre = gson.fromJson(contract.getAuthorizerInfo(), OrderAuthorizerRequest[].class);
        List<OrderAuthorizerRequest> preList = Arrays.asList(pre);
        Map<String, OrderAuthorizerRequest> preMap = preList.stream().filter(a -> a.getAuthorizerIdCardNumber() != null)
                .collect(Collectors.toMap(OrderAuthorizerRequest::getAuthorizerIdCardNumber, Function.identity(),
                        (key1, key2) -> key2));
        List<OrderAuthorizerRequest> currList = request.getCurrAuthorizerInfo();

        List<AuthorizerModifyRequest> diffAuthorizerList = new ArrayList<>();
        for (OrderAuthorizerRequest authorizer : currList) {
            // 遍历新纪录，在历史记录里找不到
            if (preMap.get(authorizer.getAuthorizerIdCardNumber()) == null) {
                // 新增
                AuthorizerModifyRequest modifyRequest = new AuthorizerModifyRequest();
                modifyRequest.setType(AuthorizerEnum.OperateType.ADD);
                modifyRequest.setTypeDesc(AuthorizerEnum.OperateType.ADD.operate);
                BeanUtil.copyProperties(authorizer, modifyRequest);
                diffAuthorizerList.add(modifyRequest);
            } else {
                if (!preMap.get(authorizer.getAuthorizerIdCardNumber()).getAuthorizerPhone().equals(authorizer.getAuthorizerPhone())) {
                    // 修改
                    AuthorizerModifyRequest modifyRequest = new AuthorizerModifyRequest();
                    modifyRequest.setType(AuthorizerEnum.OperateType.UPDATE);
                    modifyRequest.setTypeDesc(AuthorizerEnum.OperateType.UPDATE.operate);
                    BeanUtil.copyProperties(authorizer, modifyRequest);
                    diffAuthorizerList.add(modifyRequest);
                }
            }
        }
        Map<String, OrderAuthorizerRequest> currMpa =
                currList.stream().collect(Collectors.toMap(OrderAuthorizerRequest::getAuthorizerIdCardNumber,
                        Function.identity(), (key1, key2) -> key2));
        for (OrderAuthorizerRequest re : preList) {
            // 遍历历史记录，在新的记录里找不到
            if (re.getAuthorizerIdCardNumber() != null && currMpa.get(re.getAuthorizerIdCardNumber()) == null) {
                // 删除
                AuthorizerModifyRequest modifyRequest = new AuthorizerModifyRequest();
                modifyRequest.setType(AuthorizerEnum.OperateType.DELETE);
                modifyRequest.setTypeDesc(AuthorizerEnum.OperateType.DELETE.operate);
                BeanUtil.copyProperties(re, modifyRequest);
                diffAuthorizerList.add(modifyRequest);
            }
        }

        // 变更之前的授权人
        authorizerModifyPo.setPreAuthorizerInfo(contract.getAuthorizerInfo());
        // 变更的授权人
        if (CollectionUtil.isNotEmpty(diffAuthorizerList)) {
            authorizerModifyPo.setDiffAuthorizerInfo(gson.toJson(diffAuthorizerList));
        }
        // 变更之后的授权人
        authorizerModifyPo.setCurrAuthorizerInfo(gson.toJson(request.getCurrAuthorizerInfo()));

        authorizerModifyPo.setModifyReason(request.getModifyReason());
        authorizerModifyPo.setFileUrl(request.getFileUrl());

        return authorizerModifyPo;
    }

    /**
     * 删除变更的记录
     *
     * @param modifyId 变更id
     */
    private void updateAuthorizerModify(Long modifyId) {
        AuthorizerModifyPo authorizerModifyNew = new AuthorizerModifyPo();
        UserContextUtil.initUpdaterInfo(authorizerModifyNew);
        authorizerModifyNew.setIsDeleted(true);
        authorizerModifyNew.setUpdateTime(LocalDateTime.now());
        update(authorizerModifyNew, Wrappers.lambdaUpdate(AuthorizerModifyPo.class).eq(AuthorizerModifyPo::getModifyId,
                modifyId));
    }

    /**
     * 给区域经理审批
     *
     * @param authorizerModify 授权变更信息
     * @return 发起审批结果
     */
    private StartProcessInstanceResponse sendAreaManagerApprove(AuthorizerModifyPo authorizerModify) {
        StartProcessInstanceRequest approveReq = new StartProcessInstanceRequest();
        approveReq.setUserId(UserContextUtil.getCurrentUserId());
        approveReq.setProcessDefinitionId(processDefinitionId);
        Map<String, Object> params = BeanUtil.beanToMap(authorizerModify);
        params.put("rejectCount", "0");
        params.put("modifyType", "授权人变更");
        params.put("businessStatus", authorizerModify.getStatus());
        params.put("businessStatusDesc", AuthorizerEnum.Status.getDesc(authorizerModify.getStatus()));
        params.put("taskName", AuthorizerEnum.Status.getDesc(authorizerModify.getStatus()));
        params.put("contractTypeDesc", ContractTypeEnum.getDescByType(authorizerModify.getContractType()));
        approveReq.setProcessVariables(params);
        return flowProcessClient.start(approveReq);
    }

    /**
     * 更新合同授权人信息
     *
     * @param authorizerModify 授权人实体对象
     */
    private void updateContractAuthorizer(AuthorizerModifyPo authorizerModify) {
        ContractPo contract = new ContractPo();
        UserContextUtil.initUpdaterInfo(contract);
        contract.setUpdateTime(LocalDateTime.now());
        contract.setContractId(authorizerModify.getContractId());
        contract.setAuthorizerInfo(authorizerModify.getCurrAuthorizerInfo());
        contractMapper.updateById(contract);
    }

    /**
     * 更新订单授权人信息
     *
     * @param authorizerModify 授权人实体对象
     */
    private void updateOrderAuthorizer(AuthorizerModifyPo authorizerModify) {
        UpdateAuthorizerRequest request = new UpdateAuthorizerRequest();
        request.setOrderId(authorizerModify.getOrderId());
        request.setNewAuthorizerInfo(authorizerModify.getCurrAuthorizerInfo());
        orderFeignClient.updateAuthorizer(request);
    }

    /**
     * 撤回或者驳回，编辑之后重新发起审批
     *
     * @param authorizerModify 授权人变更信息
     * @param request          授权人变更请求
     */
    private void reApprove(AuthorizerModifyPo authorizerModify, SaveAuthorizerModifyRequest request) {
        authorizerModify.setStatus(AuthorizerEnum.Status.TO_APPROVE.getStatus());
        authorizerModify.setSubStatus(AuthorizerEnum.SubStatus.TO_AREA_MANAGER_APPROVE.getSubStatus());
        String taskId = this.queryNextTask(authorizerModify.getWorkflowId());
        authorizerModify.setTaskId(taskId);
        saveOrUpdate(authorizerModify);

        ApprovalTaskRequest approveRequest = new ApprovalTaskRequest();
        approveRequest.setProcessInstanceId(authorizerModify.getWorkflowId());
        approveRequest.setTaskId(taskId);
        approveRequest.setApprovalStatus(ApprovalStatusEnum.RESUBMIT.getCode());
        Map<String, Object> variables = new HashMap<>();
        variables.put("areaManagerApproveResult", AuthorizerEnum.ApproveResult.PASS.getCode());
        variables.put("businessStatus", authorizerModify.getStatus());
        variables.put("businessStatusDesc", AuthorizerEnum.Status.getDesc(authorizerModify.getStatus()));
        approveRequest.setVariables(variables);
        approveRequest.setComment("重新提交");
        if (!flowTaskClient.complete(approveRequest).getSuccess()) {
            throw new HMYRuntimeException(502000005);
        }
    }

    /**
     * 查询下一个任务节点的id
     *
     * @param processInstanceId 流程实例id
     * @return taskId 个节点的任务id
     */
    private String queryNextTask(String processInstanceId) {
        QueryNextActiveTaskRequest request = new QueryNextActiveTaskRequest();
        request.setProcessInstanceId(processInstanceId);
        return flowTaskClient.queryNextActiveTask(request);
    }
}
